package com.bright.ghj.common.util;

import com.bright.ghj.common.util.StringUtil;
import com.bright.ghj.common.pojo.query.PageQuery;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.List;
import java.util.Map;

/**
 * @Author hxj
 * @Date 2024/2/1 11:20
 * @Description
 */
public class EntityManagerUtil {

    /**
     * 是否达梦数据库
     * 注意：这个值会被DBTypeConstants方法更新 在初始化时会读取配置文件database.type 判断数据库类型
     */
    public static boolean IS_DM = false;

    public static Long queryForCount(EntityManager entityManager, String querySQL, Map<String, Object> params) {
        // 转换达梦语法
        String sql = convertByGrammar(querySQL);
        Query countNativeQuery = getNativeQuery(entityManager, sql, params);
        return Long.valueOf(countNativeQuery.getSingleResult().toString());
    }

    public static List<Map<String, Object>> queryForMapList(EntityManager entityManager, String querySQL, Map<String, Object> params, PageQuery pageQuery) {
        String sql = convertByGrammar(querySQL);
        Query nativeQuery = getNativeQuery(entityManager, sql, params);
        nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        // 实现分页
        nativeQuery.setFirstResult((pageQuery.getPageNumber()-1) * pageQuery.getPageSize());
        nativeQuery.setMaxResults(pageQuery.getPageSize());
        return nativeQuery.getResultList();
    }

    // 不分页
    public static List<Map<String, Object>> queryForMapList(EntityManager entityManager, String querySQL, Map<String, Object> params) {
        // 转换达梦语法
        String sql = convertByGrammar(querySQL);

        Query nativeQuery = getNativeQuery(entityManager, sql, params);
//        nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        // 用上面的新写法会报错“类型转换失败”
        nativeQuery.unwrap(org.hibernate.SQLQuery.class)
                .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return nativeQuery.getResultList();
    }

    public static <T> List<T> queryForClass(EntityManager entityManager, String querySQL, Map<String, Object> params, Class<T> clazz, PageQuery pageQuery) {
        String sql = convertByGrammar(querySQL);
        Query nativeQuery = getNativeQuery(entityManager, sql, params);
        nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(clazz));
        // 实现分页
        nativeQuery.setFirstResult((pageQuery.getPageNumber()-1) * pageQuery.getPageSize());
        nativeQuery.setMaxResults(pageQuery.getPageSize());
        return nativeQuery.getResultList();
    }

    // 不分页
    public static <T> List<T> queryForClass(EntityManager entityManager, String querySQL, Map<String, Object> params, Class<T> clazz) {
        // 转换达梦语法
        String sql = convertByGrammar(querySQL);
        Query nativeQuery = getNativeQuery(entityManager, sql, params);
//        nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(clazz));
        nativeQuery.unwrap(org.hibernate.SQLQuery.class)
                .setResultTransformer(Transformers.aliasToBean(clazz));
        return nativeQuery.getResultList();
    }

    // 更新
    public static void update(EntityManager entityManager, String updateSQL, Map<String, Object> params) {
        String sql = convertByGrammar(updateSQL);
        Query nativeQuery = getNativeQuery(entityManager, sql, params);
        nativeQuery.executeUpdate();
    }

    private static Query getNativeQuery(EntityManager entityManager, String querySql, Map<String, Object> params) {
        Query nativeQuery = entityManager.createNativeQuery(querySql);
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            nativeQuery.setParameter(entry.getKey(), entry.getValue());
        }
        return nativeQuery;
    }

    private static String convertByGrammar(String querySQL) {
        String sql = querySQL;
        if (IS_DM) {
            sql = StringUtil.replace(sql, "..", ".");
            sql = StringUtil.replace(sql, "[", "");
            sql = StringUtil.replace(sql, "]", "");

            sql = StringUtil.replace(sql, "with(nolock)", "");
        }
        return sql;
    }



}
